﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Practices.Unity;

namespace Vit.Common
{
    public class UnityService<T> : IService<T> where T : IProvider
    {
        protected IUnityContainer unity;
        protected List<T> providers;

        public UnityService(IUnityContainer unity)
        {
            this.unity = unity;
        }

        public void Run(Func<T, bool> action)
        {
            if (Providers == null)
                return;
            foreach (T p in Providers)
            {
                if (action(p))
                    break;
            }
        }

        public TM Run<TM>(Func<T, TM> action, Predicate<TM> breakNextProvicerAction)
        {
            if (Providers == null)
                return default(TM);

            foreach (T p in Providers)
            {
                TM obj = action(p);
                if (breakNextProvicerAction(obj))
                {
                    return obj;
                }
            }

            return default(TM);
        }

        #region IService<T> Members

        public IEnumerable<T> Providers
        {
            get
            {
                if (providers == null || providers.Count() <= 0)
                {
                    providers = new List<T>();
                    if (unity.IsRegistered<T>())
                    {
                        var provider = unity.Resolve<T>();
                        providers.Add(provider);
                        var providerInstants = unity.ResolveAll<T>();
                        providers.AddRange(providerInstants);
                    }
                }
                return providers;
            }
        }

        #endregion
    }
}
